/*
 * 评测单词选择弹窗
 */

import * as React from 'react';
import { connect } from 'react-redux';
import { get } from 'lodash';
import { Input, Form, Icon, Tag, Tooltip, Card, Button } from 'antd';

import { isEqualWithNumber } from 'utils/utils';
import CustomModal from 'components/common/CustomModal';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadableCustomPagination = LoadableComponent(() =>
  import('components/common/CustomPagination')
);
const LoadableSearchForm = LoadableComponent(() => import('./SearchForm'));

import { fetchWordList, fetchLevelList } from 'actions/review';
//import './PopToSelect.scss';

// loading由调用方下发
interface PopToSelectProps {
  dispatch: (action: any) => any;
  onCancel: () => any;
  onOk: (items: object[]) => any;
  form: any;
  loading: boolean;
  wordTotal: number;
  words: object[];
  ownItems?: any[];
  selectMax?: number;
  levels: any[];
}

interface PopToSelectState {
  selectedItems: any;
}

class PopToSelect extends React.Component<PopToSelectProps, PopToSelectState> {
  pageInit: number;
  pageSizeInit: number;
  filters: any;

  static defaultProps: PopToSelectProps = {
    dispatch: () => {},
    onCancel: () => {},
    onOk: () => {},
    form: {},
    loading: false,
    wordTotal: 0,
    words: [],
    ownItems: [],
    levels: [],
    selectMax: 0,
  };
  constructor(props: PopToSelectProps) {
    super(props);
    this.state = {
      selectedItems: get(props, 'ownItems', []),
    };

    this.pageInit = 1;
    this.pageSizeInit = 10;
    this.filters = {
      page: this.pageInit,
      pageSize: this.pageSizeInit,
    };
  }

  componentWillReceiveProps(nextProps: any) {
    if (nextProps.ownItems.length !== this.state.selectedItems.length) {
      this.setState({
        selectedItems: nextProps.ownItems,
      });
    }
  }

  componentDidMount() {
    this.handleFetchWordList();
    this.handleFetchLevels();
  }

  // 分页回调
  onPageChange = (page: number) => {
    this.handleFetchWordList({ page });
  };

  handleFetchLevels() {
    const { dispatch } = this.props;
    dispatch(
      fetchLevelList({
        page: 1,
        pageSize: 99,
      })
    );
  }

  handleFetchWordList = (params: any = {}, isSearch: boolean = false) => {
    const { dispatch } = this.props;
    this.filters = { ...this.filters, ...params };
    if (isSearch) {
      this.filters.page = this.pageInit;
    }

    dispatch(fetchWordList(this.filters));
  };

  handleTrashItem(id: number) {
    const { selectedItems } = this.state;

    let itemIndex = -1;
    selectedItems.some((item: any, index: number) => {
      if (item['id'] === id) {
        itemIndex = index;

        return true;
      }

      return false;
    });

    if (itemIndex >= 0) {
      selectedItems.splice(itemIndex, 1);
    }

    this.setState({
      selectedItems,
    });
  }

  handleCheckChange = (item: any, checked: boolean) => {
    const { selectedItems } = this.state;
    const { selectMax } = this.props;

    if (checked) {
      if (!selectMax || selectedItems.length < selectMax) {
        selectedItems.push(item);
        this.setState({
          selectedItems,
        });
      }
    } else {
      this.handleTrashItem(item.id);
    }
  };

  handleReset = () => {
    this.props.form.resetFields();
  };

  handleSearch = (e: any) => {
    e.preventDefault();

    const { form } = this.props;

    form.validateFields((err: any, values: any) => {
      if (err) return;

      let filters: any = {};
      Object.keys(values).map((key: any) => {
        const val = values[key];
        if (val) {
          filters[key] = val;
        }
      });

      this.handleFetchWordList(filters, true);
    });
  };

  handleSubmit = () => {
    const { onOk } = this.props;
    const { selectedItems } = this.state;
    onOk(selectedItems);
  };

  renderWords() {
    const { words, selectMax } = this.props;
    const { selectedItems } = this.state;

    let renderHtml = null;
    if (words.length > 0) {
      const disabled = selectMax && selectedItems.length === selectMax;
      renderHtml = words.map((word: any) => {
        let actions = null;
        if (
          !disabled ||
          (selectedItems.length > 0 && isEqualWithNumber(selectedItems[0]['id'], word.id))
        ) {
          actions = {
            onChange: (checked: boolean) => {
              this.handleCheckChange(word, checked);
            },
          };
        }
        return (
          <Tooltip title={word.description} key={word.id}>
            <Tag.CheckableTag
              key={word.id}
              checked={selectedItems.some((item: any) => {
                return item.id === word.id;
              })}
              {...actions}>
              {word.word}&nbsp;&nbsp;
            </Tag.CheckableTag>
          </Tooltip>
        );
      });
    } else {
      renderHtml = (
        <p className="loading-placeholder">
          <Icon type="frown-o" />&nbsp; 还未添加单词
        </p>
      );
    }
    return renderHtml;
  }

  renderFooterSelected = () => {
    const { selectedItems } = this.state;

    return (
      <Card title="选择的单词" style={{ textAlign: 'left' }}>
        {selectedItems.length > 0 ? (
          selectedItems.map((item: any) => {
            return (
              <Tooltip title={item.description} key={item.id}>
                <Tag>
                  {item.word}&nbsp;&nbsp;
                  <Icon
                    type="cross"
                    onClick={e => {
                      e.stopPropagation();
                      this.handleTrashItem(item.id);
                    }}
                  />
                </Tag>
              </Tooltip>
            );
          })
        ) : (
          <p className="loading-placeholder">
            <Icon type="frown-o" />&nbsp; 还没有选择单词哦
          </p>
        )}
      </Card>
    );
  };

  renderFooterActions = () => {
    const { loading, onCancel } = this.props;
    const { selectedItems } = this.state;

    return (
      <div style={{ margin: 24 }}>
        <Button
          key="back"
          type="ghost"
          size="large"
          onClick={e => {
            e.preventDefault();
            onCancel();
          }}>
          取消
        </Button>
        <Button
          key="submit"
          type="primary"
          size="large"
          loading={loading}
          disabled={selectedItems.length === 0}
          onClick={this.handleSubmit}>
          保存
        </Button>
      </div>
    );
  };

  render() {
    let { wordTotal, levels } = this.props;

    const paginParams = {
      current: this.filters.page,
      pageSize: this.filters.pageSize,
      total: wordTotal,
      onChange: this.onPageChange,
    };

    return (
      <CustomModal
        width={800}
        footer={
          <React.Fragment>
            {this.renderFooterSelected()}
            {this.renderFooterActions()}
          </React.Fragment>
        }>
        <Card bordered={false}>
          <LoadableSearchForm levels={levels} handleSearch={this.handleFetchWordList} />
        </Card>
        <Card id="tag_content_box" style={{ marginTop: 24, minHeight: 120 }}>
          {this.renderWords()}
          <div className="clear-both" />
          <LoadableCustomPagination {...paginParams} />
        </Card>
      </CustomModal>
    );
  }
}

interface OwnProps {
  loading: boolean;
}

function mapStateToProps(state: any, ownProps: OwnProps) {
  const { loading } = ownProps;
  const { words, wordTotal, levels } = state.review;

  return {
    loading,
    words,
    wordTotal,
    levels,
  };
}

export default connect(mapStateToProps)(Form.create()(PopToSelect));
